import Player from "../player/Player";
import GameManager from "../manager/GameManager";
import TerrainManager from "../manager/TerrainManager";
import MainHome from "../facility/priveteFacility/MainHome";
import OilWell from "../facility/priveteFacility/OilWell";
import Facility from "../facility/Facility";
import UiPointer from "../UI/UiPointer";
import DestructibleFacility from "../facility/DestructibleFacility";
import { FacilityType, GamePropType } from "../info/GameEnum";
import { Location, MapLength } from "../info/Predefine";
import { Global } from "../info/Global";
import UiManager from "../manager/UiManager";
import NoviceGuide from "../UI/NoviceGuide";
import MusicManager from "../../MusicManager";
import PlayerManager from "../manager/PlayerManager";

const { ccclass, property } = cc._decorator;

@ccclass
export default class ControlledPlayer extends Player {

    /**
     * 显示的名字
     */
    public get playerName(): string {
        return "你";
    }

    public get facilityHpColor(): cc.SpriteFrame {
        return GameManager.instance.selfHpColors[0];
    }

    public get flyerhpColor(): cc.SpriteFrame {
        return GameManager.instance.selfHpColors[1];
    }

    public get flyerParentNode(): cc.Node {
        return GameManager.instance.aboveFlyerParent;
    }

    public set showAllView(v: boolean) {
        if (v) {
            TerrainManager.instance.fog.node.active = false;
            TerrainManager.instance.bgFog.node.active = false;
            let otherPlayers = PlayerManager.instance.playerComps.filter(player => !this.discoveredEnemy.includes(player) && player !== this);
            let t = cc.tween(this);
            otherPlayers.forEach(player => {
                t.call(() => {
                    this.discoveredEnemy.push(player)
                    this.node.emit(Player.EventType.找到新的对手, player);
                })
                    .delay(0.5)
            })
            t.start();
        } else {
            TerrainManager.instance.fog.node.active = true;
            TerrainManager.instance.bgFog.node.active = true;
        }
    }

    public magicBoxTime = 0;

    protected onKillOtherPlayer(): void {
        super.onKillOtherPlayer();
        this.scheduleOnce(() => {
            let showTip = "击杀奖励";
            if (Global.KillBonus.diamond) {
                showTip += "      +" + Global.KillBonus.diamond;
            }
            if (Global.KillBonus.oil) {
                showTip += "      +" + Global.KillBonus.oil;
            }
            UiManager.instance.showTip(showTip);
        }, 1);
    }

    public addDiamondAndOil(diamond: number, oil: number, position?: cc.Vec3) {
        super.addDiamond(diamond);
        super.addOil(oil);
        if (!position) {
            position = this.facilityArr[FacilityType.主基地][0].node.position;
        }
        if (diamond) {
            GameManager.instance.showResourceTips(1, diamond, position);
        }
        if (oil) {
            GameManager.instance.showResourceTips(2, oil, position.sub(cc.v3(0, 20)));
        }
    }

    public addDiamond(value: number, position?: cc.Vec3): void {
        super.addDiamond(value);
        if (!position) {
            position = this.facilityArr[FacilityType.主基地][0].node.position.subSelf(cc.v3(0, -10))
        }
        GameManager.instance.showResourceTips(1, value, position);
    }

    public addOil(value: number, position?: cc.Vec3): void {
        super.addOil(value);
        if (!position) {
            position = this.facilityArr[FacilityType.主基地][0].node.position.subSelf(cc.v3(0, -10))
        }
        GameManager.instance.showResourceTips(2, value, position);
    }

    protected start(): void {
        super.start();
        this.getComponentInChildren(cc.Label).string = Global.currentGameData.self.nikeName;
    }
    public init(roleId: number, props: GamePropType[]): void {
        super.init(roleId, props);
        this.node.on(Player.EventType.我的设施被攻击, (fac: DestructibleFacility) => {
            if (fac.facilityType == FacilityType.主基地) {
                MusicManager.instance.play(MusicManager.instance.baseUnderAtk, fac.node);
            }
        })

        this.node.on(Player.EventType.被发现, (player: Player) => {
            UiManager.instance.showTip("你已被" + player.playerName + "发现");
        })
    }

    // public makeHome(): boolean {
    //     this.diamond += 100000;
    //     this.oil += 100000; 
    //     return super.makeHome();
    // }

    public addFacility(facilityType: FacilityType, locaitons: Location[], price: { diamond: number, oil: number } = this.getPrice(facilityType)): DestructibleFacility {
        let facility = super.addFacility(facilityType, locaitons, price);
        UiPointer.instance.currLocation = UiPointer.instance.currLocation;
        UiPointer.instance.refreshSize();
        if (facility.facilityType == FacilityType.采油机) {
            (facility as OilWell).buildTip.node.active = false;
            facility.node.on(DestructibleFacility.EventType.摧毁, this.onOilWellDie, this);
        }
        return facility;
    }

    /**
     * 当我的油矿摧毁
     */
    onOilWellDie(oilwell: OilWell) {
        oilwell.node.off(DestructibleFacility.EventType.摧毁, this.onOilWellDie, this);
        oilwell.buildTip.node.active = this.isSelfDomain(oilwell.locations[0]);
    }

    /**
     * 得到新地盘
     * 更新地盘地块
     * 更新地盘周围的视野
     * @param newDomain 
     */
    public onGetNewDomain(newDomain: Location[]): void {
        super.onGetNewDomain(newDomain);
        for (let i = 0; i < newDomain.length; i++) {
            TerrainManager.instance.setLocationDomain(newDomain[i]);
            let leftUp: Location = { locationX: Math.max(0, newDomain[i].locationX - 1), locationY: Math.max(0, newDomain[i].locationY - 1) },
                rightDown: Location = { locationX: Math.min(MapLength - 1, newDomain[i].locationX + 1), locationY: Math.min(MapLength - 1, newDomain[i].locationY + 1) };
            for (let i = leftUp.locationX; i <= rightDown.locationX; i++) {
                for (let j = leftUp.locationY; j <= rightDown.locationY; j++) {
                    this.getLocationView({ locationX: i, locationY: j });
                }
            }
        }

        //新领地中的油矿更新提示
        for (let i = 0; i < newDomain.length; i++) {
            let fac = GameManager.instance.getFacilityByLocation(newDomain[i]);
            if (fac && fac.facilityType == FacilityType.油矿) {
                let oilWell = fac.getComponent(OilWell);
                if (!oilWell.machine.node.active) {
                    oilWell.buildTip.node.active = this.isSelfDomain(oilWell.locations[0]);
                }
            }
        }
    }

    /**
     * 失去领地
     * @param domain 
     */
    public loseDomain(domain: Location[]) {
        super.loseDomain(domain);
        domain.forEach(item => TerrainManager.instance.setLocationDomain(item, 5));
        this.domainArr.forEach(item => TerrainManager.instance.setLocationDomain(item, 1));

        //领地中的油矿更新提示
        for (let i = 0; i < domain.length; i++) {
            let fac = GameManager.instance.getFacilityByLocation(domain[i]);
            if (fac && fac.facilityType == FacilityType.油矿) {
                let oilWell = fac.getComponent(OilWell);
                if (!oilWell.machine.node.active) {
                    oilWell.buildTip.node.active = this.isSelfDomain(oilWell.locations[0]);
                }
            }
        }
    }

    /**
     * 获得矩形视野
     * @param newDoamin 需要更新
     */
    public getLocationView(location: Location): void {
        //更新战争迷雾地块 ,有新发现的敌人，发送事件
        TerrainManager.instance.setLocationView(TerrainManager.instance.fog, location);
        let fac = GameManager.instance.getFacilityByLocation(location);
        if (fac && fac instanceof DestructibleFacility && fac.player !== this) {
            this.node.emit(NoviceGuide.EventType.侦察到敌人的建筑);
            if (fac instanceof MainHome && !this.discoveredEnemy.includes(fac.player)) {
                this.discoveredEnemy.push(fac.player)
                this.node.emit(Player.EventType.找到新的对手, fac.player);
            }
        }

        //更新背景战争迷雾地块
        let leftUp: Location = { locationX: Math.max(0, location.locationX - 1), locationY: Math.max(0, location.locationY - 1) },
            rightDown: Location = { locationX: Math.min(MapLength - 1, location.locationX + 1), locationY: Math.min(MapLength - 1, location.locationY + 1) };
        for (let i = leftUp.locationX; i <= rightDown.locationX; i++) {
            for (let j = leftUp.locationY; j <= rightDown.locationY; j++) {
                TerrainManager.instance.setLocationView(TerrainManager.instance.bgFog, { locationX: i, locationY: j });
            }
        }
    }

    public isLocationVisible(location: Location): boolean {
        return !TerrainManager.instance.isHide(location);
    }

    public isFacilityVisible(facility: Facility): boolean {
        return !!facility.locations.find(locaiton => this.isLocationVisible(locaiton));
    }

    protected onFindNewEnemy(player: Player): void {
    }
}
